// void, Obj This

Settlement this, sett_target;
Building bld;
Query our_units;
Unit unit;
int min_resource_food, min_resource_gold, refresh, required_gold, gold_income, reserved_food, extra_gold;
int i, j, p, s, b, k, price_peasant, l, food_tax;
int amount_fg, food_received, gold_received;
Wagon wagon;
bool bProduceGold, bSellFood, bBuyFood, bWagon, aicheck;
ObjList olUnitsTributeOut, sel;
ObjList olUnitsOut;
ObjList list, ol;
str strCommand, target_name, strMaleVillager;
Sleep(rand(1000)+1000);
this = This.AsBuilding().settlement;
bld = This.AsBuilding();

if(EnvReadInt(this, "AssignName") == 0){
	Building build;
	str names;
	
	EnvWriteInt(this, "AssignName", 1);
	if(bld.name == ""){
		names = "B_"+bld.class+"_"+bld.player+bld.race+rand(99)+rand(99);
		build = GetNamedObj(names).obj.AsBuilding;
		if(!build.IsValid){
			bld.SetName("");       
			bld.SetName(names);
		} else {
			names = "B_"+bld.class+"_"+bld.player+bld.race+rand(99)+rand(99);
			bld.SetName("");       
			bld.SetName(names);
		}  
	}
}

p = .player;

if(EnvReadInt(this, "player") != p){
	EnvWriteString(this, "tribute_food", "off");
	EnvWriteString(this, "tribute_gold", "off");
	EnvWriteString(this, "tribute_people", "off");
	                                
	EnvWriteString(this, "stoptribute_food", "on");
	EnvWriteString(this, "stoptribute_gold", "on");
	EnvWriteString(this, "stoptribute_people", "on");
	.StopSupply();
}
EnvWriteInt(this, "player", p);

refresh = GetConst("OutpostRefresh");
amount_fg = GetConst("AmountFoodAndGold");
//food_income = GetConst("GOutpostGoldReturn");
gold_income = GetConst("ROutpostGoldReturn");
required_gold = GetConst("ROutpostRequiredGold");
min_resource_food = GetConst("MinResQtyToTransportFood");
min_resource_gold = GetConst("MinResQtyToTransportGold");
price_peasant = GetConst("PricePeasant");
food_tax = GetConst("OutpostFoodProduction");
bProduceGold = This.IsHeirOf("ROutpost") || This.IsHeirOf("EOutpost");
//cost_food = 15;

if(EnvReadString(this, "Outpost Level 1") == "researched"){ 
    gold_income = gold_income + 2;
    if(EnvReadString(this, "Outpost Level 2") == "researched"){
        gold_income = gold_income + 4;
    }
}
our_units = Intersect(ObjsInCircle(This.AsBuilding.pos, 800, "Military"), ClassPlayerObjs("Military", .player));
//pr("outpost idle "+This.AsBuilding.race);
l = 0;

while (1) {
	//pr(p);
	list = our_units.GetObjList();
	list.ClearDead();
	list = list.ObjInjured();
	k = list.count;
	j = rand(k);
	if(k > 0){
		unit = list[j].AsUnit();
		if(unit.IsValid){
			if(This.AsBuilding.race == unit.race){
				if(.IsIndependent)
					unit.Heal(20);
				else
					unit.Heal(400);
					
				CreateFeedback("Heal", unit);
			}
		}
	}
	
	if (.IsIndependent())
	{
		Sleep(refresh);
		continue;
	}
	Sleep(refresh);

	if(p != .player){
		EnvWriteString(this, "tribute_food", "off");
		EnvWriteString(this, "tribute_gold", "off");
		EnvWriteString(this, "tribute_people", "off");
								
		EnvWriteString(this, "stoptribute_food", "on");
		EnvWriteString(this, "stoptribute_gold", "on");
		EnvWriteString(this, "stoptribute_people", "on");
		.StopSupply();
		break;
	}
	if(EnvReadString(.player, "Food Tax Outpost") == "yes"){
		.SetFood(.food + food_tax);
	}
	l+=1;

	if(l >= 10){
		l = 0;
		if(EnvReadString(this, "buying_peasants") == "yes"){
			if(.gold >= price_peasant){
				Unit u;
				strMaleVillager = bld.raceStrPref;
				strMaleVillager = strMaleVillager + "Villager";
				u = Place(strMaleVillager, bld.pos, .player);
				if(u.IsValid) .ForceAddUnit(u);
				if(price_peasant > 0){
					.SetGold(.gold - price_peasant);
					.GoldSpent(-price_peasant);
					.GoldConverted(.gold - price_peasant);
				}
			}
		} else if(EnvReadString(this, "selling_peasants") == "yes"){
			ol = .Units.ObjClass("Peasant");
			ol.ClearDead();
			ol = ol.ObjAlly(.player);
			if(ol.count > 0){
				Unit u; 
				u = ol[0].AsUnit;
				if(u.IsValid){
					if(u.IsHeirOf("Peasant")){
						if(u.player == .player){
							u.Erase();
							//Sleep(rand(100)+100);
							if(price_peasant > 0){
								.SetGold(.gold + price_peasant);
								.GoldConverted(price_peasant);
							}
						}
					}
				}
			}
		}
	}
	bSellFood = EnvReadString(this, "GOutpostSellFood") == "yes";
	bBuyFood = EnvReadString(this, "GOutpostBuyFood") == "yes";
	// gaul outpost behaviour
	b = EnvReadInt(this, "BuyingFood");
	food_received = amount_fg * b / 100;
	EnvWriteInt(this, "FoodReceived", food_received);
	
	if (!bProduceGold && bBuyFood && .gold > amount_fg && !bSellFood) {
		if(amount_fg > 0){
			.SetGold(.gold - amount_fg);
			.GoldSpent(-amount_fg);
			.GoldConverted(.gold - amount_fg);
		}
		
		if(food_received > 0) .SetFood(.food + food_received);
	}
	s = EnvReadInt(this, "SaleFood");
	gold_received = amount_fg * s / 100;
	EnvWriteInt(this, "GoldReceived", gold_received);
        
	if (!bProduceGold && bSellFood && .food > amount_fg && !bBuyFood) {
		if(amount_fg > 0) .SetFood(.food - amount_fg);
		if(gold_received > 0){
			.SetGold(.gold + gold_received);
			.GoldConverted(gold_received);
		}
	}
	if(.gold >= 2000 && .gold < 3000){
		if(extra_gold != 0)
			extra_gold = 0;
		if(required_gold != 2000)
			required_gold = 2000;
	} else if(.gold >= 3000 && .gold < 4000){
		if(extra_gold != 1)
			extra_gold = 1;
		if(required_gold != 3000)
			required_gold = 3000;
	} else if(.gold >= 4000 && .gold < 5000){
		if(extra_gold != 2)
			extra_gold = 2;
		if(required_gold != 4000)
			required_gold = 4000;
	} else if(.gold >= 5000 && .gold < 6000){
		if(extra_gold != 3)
			extra_gold = 3;
		if(required_gold != 5000)
			required_gold = 5000;
	} else if(.gold >= 6000 && .gold < 7000){
		if(extra_gold != 4)
			extra_gold = 4;
		if(required_gold != 6000)
			required_gold = 6000;
	} else if(.gold >= 7000 && .gold < 8000){
		if(extra_gold != 5)
			extra_gold = 5;
		if(required_gold != 7000)
			required_gold = 7000;
	} else if(.gold >= 8000 && .gold < 9000){
		if(extra_gold != 6)
			extra_gold = 6;
		if(required_gold != 8000)
			required_gold = 8000;
	} else if(.gold >= 9000 && .gold < 10000){
		if(extra_gold != 7)
			extra_gold = 7;
		if(required_gold != 9000)
			required_gold = 9000;
	} else if(.gold >= 10000){
		if(extra_gold != 8)
			extra_gold = 8;
		if(required_gold != 10000)
			required_gold = 10000;
	}
	// roman outpost behaviour
	if(bProduceGold && .gold >= required_gold) {
		.SetGold(.gold + (gold_income+extra_gold));
		.GoldConverted(gold_income+extra_gold);
	}
	// send resources
	aicheck = true;
	if (.supplied == this)
		.StopSupply();
	if (!.supplied.IsValid()) aicheck = false;
	if(aicheck) if (!DiplGetCeaseFire(.player, .supplied.player)) aicheck = false;
	bWagon = false;
	if(EnvReadString(this, "tribute_gold") == "on" || (IsAIPlayer(p) && aicheck)){
		target_name = EnvReadString(this, "tribute_gold_target");
		sett_target = GetNamedObj(target_name).obj.AsBuilding.settlement;

		if(sett_target.IsValid || (IsAIPlayer(p) && aicheck)){
			if(.IsEnemy(sett_target.player)) {
				EnvWriteString(this, "tribute_gold", "off");
				EnvWriteString(this, "stoptribute_gold", "on");
				continue;
			}
			if(.gold > min_resource_gold) {
				int gold;
				gold = 1000;
				if (bProduceGold && .gold > required_gold && .gold - required_gold < 1000){
					if(!EnvReadString(this, "burn") == "yes")
						gold = .gold - required_gold;
				}
				if (gold > min_resource_gold) {
					if(IsAIPlayer(p) && aicheck){
						wagon = .CreateMuleGold(gold);
						if(wagon.IsValid)
							wagon.SetCommand("unload", .supplied.GetCentralBuilding());
						bWagon = true;
					} else {
						wagon = .CreateMuleGold(gold);
						if(wagon.IsValid){
							wagon.SetCommand("unload", sett_target.GetCentralBuilding());
							wagon.AddCommand(false, "unload", .GetCentralBuilding());
						}
						bWagon = true;
					}
				}
			}
			sel = _GetSelection().ObjAlly(.player).ObjClass("Outpost");
			if(sel.count == 1){
				Building tw;
				
				tw = sel[0].AsBuilding;
				if(tw.IsValid){
					if(tw == .GetCentralBuilding){
						//UserNotification("tribute people", "", Point(target_x, target_y), .player); 
						UserNotification("tribute gold", "", sett_target.GetCentralBuilding.pos, .player); 
						//UserNotification("tribute food", "", sett_target.GetCentralBuilding.pos, .player); 
					}
				}
			}
		}
	}

	if (.Units.count)
		reserved_food = 500;
	else
		reserved_food = 0;
	
	if(EnvReadString(this, "tribute_food") == "on" || (IsAIPlayer(p) && aicheck)){
		target_name = EnvReadString(this, "tribute_food_target");
		sett_target = GetNamedObj(target_name).obj.AsBuilding.settlement;

		if(sett_target.IsValid || (IsAIPlayer(p) && aicheck)){
			if(.IsEnemy(sett_target.player)) {
				EnvWriteString(this, "tribute_food", "off");
				EnvWriteString(this, "stoptribute_food", "on");
				.StopSupply();
				continue;
			}
			if (!bWagon && .food > (min_resource_food + reserved_food) && !bSellFood) {
				if(IsAIPlayer(p) && aicheck){
					if (.food - reserved_food > 1000)
						wagon = .CreateMuleFood(1000);
					else
						wagon = .CreateMuleFood(.food - reserved_food);
					
					if(wagon.IsValid)	
						wagon.SetCommand("unload", .supplied.GetCentralBuilding());
				
				} else {
					if (.food - reserved_food > 1000)
						wagon = .CreateMuleFood(1000);
					else
						wagon = .CreateMuleFood(.food - reserved_food);
					
					if(wagon.IsValid){	
						wagon.SetCommand("unload", sett_target.GetCentralBuilding());
						wagon.AddCommand(false, "unload", .GetCentralBuilding());   
					}
				}
			}
			sel = _GetSelection().ObjAlly(.player).ObjClass("Outpost");
			if(sel.count == 1){
				Building tw;
				
				tw = sel[0].AsBuilding;
				if(tw.IsValid){
					if(tw == .GetCentralBuilding){
						UserNotification("tribute food", "", sett_target.GetCentralBuilding.pos, .player); 
					}
				}
			}
		}
	}
	
	if(EnvReadString(this, "tribute_people") == "on"){
		Unit u;
		
		olUnitsTributeOut.Clear;
		for(i=0; i<.Units.count; i+=1) {
			u = .Units[i].AsUnit;
			if(!u.IsValid) continue;
			if(!u.IsHeirOf("SentryOutpost")
			&& !u.IsHeirOf("CaptainOutpost")
			&& !u.IsHeirOf("Wagon")) {
				if(!u.hero.IsValid){
					if(u.IsHeirOf("Peasant")){
						if(bld.race==Germany || bld.race==Gaul){
							if(EnvReadString(this, "selling_peasants") != "yes")
									olUnitsTributeOut.Add(u);
						} else {
							if(EnvReadString(this, "train_peasants") != "yes")
								olUnitsTributeOut.Add(u);
						}
					} else if(u.IsHeirOf("Hero")){
						if(!u.AsHero.HasArmy)
							olUnitsTributeOut.Add(u);
					} else {
						olUnitsTributeOut.Add(u);
					}
				}
			}
			if(olUnitsTributeOut.count >= 7) break;
		}
		{
			int target_x, target_y;
			point pos, pp;
			rect rc;
			
			target_name = EnvReadString(this, "tribute_people_target");
			sett_target = GetNamedObj(target_name).obj.AsBuilding.settlement;                        
			target_x = EnvReadInt(this, "tribute_people_target_x");
			target_y = EnvReadInt(this, "tribute_people_target_y");
			if(sett_target.IsValid){
				Building bld_target;
				bld_target = sett_target.GetCentralBuilding;
				if(!.IsEnemy(sett_target.player)){
					if(olUnitsTributeOut.count >= 1){
						if(bld_target.IsHeirOf("Outpost") ||
						   bld_target.IsHeirOf("BaseShipyard") ||
						   bld_target.IsHeirOf("IronMine") ||
						   bld_target.IsHeirOf("BaseTownhall")){
						   
							olUnitsTributeOut.SetCommand("enter", bld_target);
								
						} else {
							rc = GetMapRect();
							pos.Set(0, bld_target.sight / 3);
							pos.Rot(rand(360));     pp = pos + bld_target.pos; pp.IntoRect(rc); 
							olUnitsTributeOut.SetCommand("move", pp);
						}
						//Sleep(4*1000);
					}
				} else {
					EnvWriteString(this, "tribute_people", "off");
					EnvWriteString(this, "stoptribute_people", "on");
				}
				sel = _GetSelection().ObjAlly(.player).ObjClass("Outpost");
				if(sel.count == 1){
					Building tw;
					
					tw = sel[0].AsBuilding;
					if(tw.IsValid){
						if(tw == .GetCentralBuilding){
							UserNotification("tribute people", "", bld_target.pos, .player); 
							//UserNotification("tribute gold", "", Point(target_x, target_y), .player); 
							//UserNotification("tribute food", "", Point(target_x, target_y), .player); 
						}
					}
				}
			} else if(target_x != 0 && target_y != 0){
				if(olUnitsTributeOut.count >= 1){
					rc = GetMapRect();
					pos.Set(0, 200);
					pos.Rot(rand(360));     pp = pos + Point(target_x, target_y); pp.IntoRect(rc); 
					olUnitsTributeOut.SetCommand("move", pp);

					//Sleep(4*1000);
				}
				sel = _GetSelection().ObjAlly(.player).ObjClass("Outpost");
				if(sel.count == 1){
					Building tw;
					
					tw = sel[0].AsBuilding;
					if(tw.IsValid){
						if(tw == .GetCentralBuilding){
							UserNotification("tribute people", "", Point(target_x, target_y), .player); 
							//UserNotification("tribute gold", "", Point(target_x, target_y), .player); 
							//UserNotification("tribute food", "", Point(target_x, target_y), .player); 
						}
					}
				}
			}
		}
	}
}
